package com.ruin.app.util;

import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateHelper;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import javax.swing.text.Highlighter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * elasticsearch 工具
 */
public class ElasticUtil {

    public static TransportClient transportClient;


    private ElasticUtil() {
    }

    public static TransportClient getInstance() {
        return transportClient;
    }

    static {
        Settings settings = Settings.builder().put("cluster.name", "rzos-app").build();
        try {
            transportClient = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }


    public static Map<String, Object> getIndex(String index, String type, String id) throws UnknownHostException {
        GetResponse response = transportClient.prepareGet(index, type, id).get();
        return response.getSource();
    }

    public static DocWriteResponse.Result addIndex(String index, String type, String id, Map map) throws UnknownHostException {
        IndexResponse indexResponse = transportClient.prepareIndex(index, type, id).setSource(map).execute().actionGet();
        return indexResponse.getResult();
    }

    public static DocWriteResponse.Result updateIndex(String index, String type, String id, Map map) throws UnknownHostException {
        UpdateResponse response = transportClient.prepareUpdate(index, type, id).setDoc(map).get();
        return response.getResult();
    }

    public static List<Map<String, Object>> searchIndex(String index, String type) throws UnknownHostException {
        List<Map<String, Object>> datas = new ArrayList<>();
        SearchResponse response = transportClient.prepareSearch(index)
                .setTypes(type).setSearchType(SearchType.DEFAULT).execute().actionGet();

        SearchHit[] searchHits = response.getHits().getHits();

        for (SearchHit searchHit : searchHits) {
            datas.add(searchHit.getSource());
        }
        return datas;
    }

    public static List<Map<String, Object>> searchData(String index, String type, String name, String keyWord) throws UnknownHostException {
        List<Map<String, Object>> datas = new ArrayList<>();
        SearchResponse response = transportClient.prepareSearch(index)
                .setTypes(type).setSearchType(SearchType.DEFAULT)
                .setQuery(QueryBuilders.wildcardQuery(name, "*"+keyWord+"*")).highlighter(new HighlightBuilder().field(name).preTags("<span class=\"text-danger\">").postTags("</span>")).get();
        SearchHit[] searchHits = response.getHits().getHits();

        for (SearchHit searchHit : searchHits) {
            Text[] texts = searchHit.getHighlightFields().get(name).getFragments();
            String str = "";
            for (Text text : texts) {
                str += text.string();
            }

            Map<String, Object> source = searchHit.getSource();
            source.replace(name, str);
            datas.add(source);
        }
        return datas;
    }
}
